package cn.piesat.service.impl;

import cn.piesat.dao.PiesatUserLogDAO;
import cn.piesat.dto.PiesatUserLogDTO;
import cn.piesat.service.intf.UserLogService;
import cn.piesat.util.PageUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日志相关 服务层实现类
 */
@Service
public class UserLogServiceImpl implements UserLogService {

    @Autowired
    private PiesatUserLogDAO piesatUserLogDAO;

    @Override
    public Map<String, Object> listLog(Integer pageNum, Integer pageSize, PiesatUserLogDTO logDTO) {
        Pageable pageable = PageRequest.of(pageNum,pageSize, Sort.by(Sort.Direction.DESC,"createTime"));
        Page<PiesatUserLogDTO> page = piesatUserLogDAO.findAll(new Specification<PiesatUserLogDTO>() {
            @Override
            public Predicate toPredicate(Root<PiesatUserLogDTO> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                if (StringUtils.isNotBlank(logDTO.getOperation())){
                    predicates.add(cb.like(root.get("operation"),"%"+logDTO.getOperation()+"%"));
                }
                if(logDTO.getLogType() != null){
                    predicates.add(cb.equal(root.get("logType"),logDTO.getLogType()));
                }
                if (StringUtils.isNotBlank(logDTO.getCreateTimeFrom()) && StringUtils.isNotBlank(logDTO.getCreateTimeTo())){
                    predicates.add(cb.greaterThanOrEqualTo(root.get("createTime").as(String.class),logDTO.getCreateTimeFrom()));
                    predicates.add(cb.lessThanOrEqualTo(root.get("createTime").as(String.class),logDTO.getCreateTimeTo()));
                }
                return cb.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        }, pageable);
        return PageUtil.getPage(page);
    }

    @Override
    public Map<String, Object> getLoginChartData() {
        //当前时间1内每月的登录次数
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        String currentTime = format.format(calendar.getTime());
        calendar.add(Calendar.MONTH, -1);
        String beforeMonth = format.format(calendar.getTime());
        calendar.add(Calendar.YEAR,-1);
        String beforeYear = format.format(calendar.getTime());

        List<Object[]> loginMonthData = piesatUserLogDAO.getLoginMonthData(beforeYear, currentTime);
        List<Map<String,Object>> loginMonthList = new ArrayList<>();
        loginMonthData.forEach(obj -> {
            Map<String,Object> map = new HashMap<>();
            map.put("name",obj[1]);
            map.put("value",obj[0]);
            loginMonthList.add(map);
        });

        List<Object[]> loginTopTen = piesatUserLogDAO.getLoginTopTen(beforeMonth, currentTime);
        List<Map<String,Object>> loginTopTenList = new ArrayList<>();
        loginTopTen.forEach(obj -> {
            Map<String,Object> map = new HashMap<>();
            map.put("name",obj[1]);
            map.put("value",obj[0]);
            loginTopTenList.add(map);
        });

        Map<String,Object> returnMap = new HashMap<>();
        returnMap.put("bar",loginMonthList);
        returnMap.put("pie",loginTopTenList);
        return returnMap;
    }

    @Override
    public Map<String, Object> getBusiChartData() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();
        String currentTime = format.format(calendar.getTime());
        calendar.add(Calendar.MONTH, -1);
//        calendar.add(Calendar.YEAR,-1);
        String beforeMonth = format.format(calendar.getTime());
        List<Object[]> busiTopTen = piesatUserLogDAO.getBusiTopTen(beforeMonth, currentTime);
        List<Map<String,Object>> busiTopTenList = new ArrayList<>();
        busiTopTen.forEach(obj -> {
            Map<String,Object> map = new HashMap<>();
            map.put("name",obj[1]);
            map.put("value",obj[0]);
            busiTopTenList.add(map);
        });
        Map<String,Object> returnMap = new HashMap<>();
        returnMap.put("pie",busiTopTenList);
        return returnMap;
    }
}
